package com.fll.user.client;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fll.thrift.user.dto.UserDto;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;


/**
 * @Description
 * @Author fanlei
 * @Version 1.0
 * @Date 2018年09月02日
 */
public abstract class LoginFilter implements Filter {



    private static Cache<String,UserDto> cache = CacheBuilder.newBuilder()
            .maximumSize(10000)
            //写入之后3min过期
            .expireAfterWrite(3, TimeUnit.MINUTES).build();


    public void init(FilterConfig filterConfig) throws ServletException {

    }


    //来一个请求验证一下，压力还是大，用goole的guava进行缓存
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String token = request.getParameter("token");
        if (StringUtils.isBlank(token)){//支持一下cookie
            Cookie[] cookies = request.getCookies();
            if(cookies != null){
                for (Cookie c :
                        cookies) {
                    if("token".equals(c.getName())){
                        token = c.getValue();
                    }
                }
            }
        }

        UserDto userDto = null;
        if(StringUtils.isNotBlank(token)){//有token
            userDto = cache.getIfPresent(token);
            if(userDto == null){
                userDto = requestUserInfo(token);
                if(userDto != null){
                    cache.put(token,userDto);
                }
            }
        }

        if (userDto == null){
            response.sendRedirect("http://192.168.0.109:8082/user/login");//zuul的路由地址转发
            return;
        }


        //本来这个客户端验证token已经成功了，还可以给客户端登陆完之后做一些事（所以用抽象方法，继承这个类必须实现ta）
        login(request,response,userDto);


        filterChain.doFilter(request,response);


    }

    protected abstract void login(HttpServletRequest request,HttpServletResponse response,UserDto userDto);

    public void destroy() {

    }

    protected UserDto requestUserInfo(String token){
        String url = "http://user-edge-service:8082/user/authentication";
        HttpClient client = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("token",token);
        InputStream inputStream = null;
        try {
            HttpResponse response = client.execute(httpPost);
            if(response.getStatusLine().getStatusCode()!= HttpStatus.SC_OK) {
                throw new RuntimeException("request user info failed! StatusLine:"+response.getStatusLine());
            }
            inputStream = response.getEntity().getContent();
            byte[] temp = new byte[1024];
            StringBuilder sb = new StringBuilder();
            int len = 0;
            while((len = inputStream.read(temp))>0) {
                sb.append(new String(temp,0,len));
            }

            UserDto userDTO = new ObjectMapper().readValue(sb.toString(), UserDto.class);
            return userDTO;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(inputStream!=null) {
                try{
                    inputStream.close();
                }catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }


}
